import { screen } from '@testing-library/react';
import { userEvent } from '@testing-library/user-event';
import { append } from 'ramda';

import { composeMockedQueryResult } from '../../../../tests/utils/fixtures';
import { render } from '../../../../tests/utils/rendering';
import { Add{{ pascalCase name }} } from '../add{{ pascalCase name }}.component';
import { add{{ pascalCase name }}Mutation } from '../add{{ pascalCase name }}.graphql';

describe('Add{{ pascalCase name }}: Component', () => {
  const Component = () => <Add{{ pascalCase name }} />;

  it('should display empty form', async () => {
    const { waitForApolloMocks } = render(<Component />);
    await waitForApolloMocks();
    const value = (await screen.findByPlaceholderText(/name/i)).getAttribute('value');
    expect(value).toBeNull();
  });

  describe('action completes successfully', () => {
    it('should commit mutation', async () => {
      const variables = {
        input: { name: 'new item name' },
      };
      const data = {
        create{{ pascalCase name }}: {
          {{ camelCase name }}Edge: {
            node: {
              id: 1,
              ...variables.input,
            },
          },
        },
      };
      const requestMock = composeMockedQueryResult(add{{ pascalCase name }}Mutation, {
        variables,
        data,
      });
      requestMock.newData = jest.fn(() => ({
        data,
      }));

      render(<Component />, { apolloMocks: append(requestMock) });

      await userEvent.type(await screen.findByPlaceholderText(/name/i), 'new item name');
      await userEvent.click(screen.getByRole('button', { name: /save/i }));
      expect(requestMock.newData).toHaveBeenCalled();
    });

    it('should show success message', async () => {
      const variables = {
        input: { name: 'new item' },
      };
      const data = {
        create{{ pascalCase name }}: {
          {{ camelCase name }}Edge: {
            node: {
              id: 1,
              ...variables.input,
            },
          },
        },
      };
      const requestMock = composeMockedQueryResult(add{{ pascalCase name }}Mutation, {
        variables,
        data,
      });

      render(<Component />, { apolloMocks: append(requestMock) });

      await userEvent.type(await screen.findByPlaceholderText(/name/i), 'new item');
      await userEvent.click(screen.getByRole('button', { name: /save/i }));

      const message = await screen.findByTestId('snackbar-message-0');
      expect(message).toHaveTextContent('🎉 Changes saved successfully!');
    });
  });
});
